// ============== if-else ============== //
type A_if = 1
type B_if = 2
type IfExample = A_if extends B_if ? true : false  // true

// ============== 模式匹配 ============== //
type A_infer = 'test123te'
type InferExample = A_infer extends `test${infer mid}te` ? mid : never  // 123

// ============== 与或非 ============== //
type AndExample<c1 extends boolean, c2 extends boolean> = c1 extends true ? c2 extends true ? true : false : false
type OrExample<c1 extends boolean, c2 extends boolean> = c1 extends true ? true : c2 extends true ? true : false
type NotExample<c1 extends boolean> = c1 extends true ? false : true

// ============== 判断相等 ============== //
// 左侧类型是否可以分配给右侧
type LExtendsRExample<T extends any, R extends any> = T extends R ? true : false

type CheckLeftIsExtendsRight<T extends any, R extends any> = T extends R ? true : false
type Not<C extends boolean> = C extends true ? false : true
type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends <T1>() => T1 extends B ? 1 : 2 ? true : false
type IsNotEqual<L extends NumberLike, R extends NumberLike, Strict extends boolean = true> = Not<IsEqual<L, R, Strict>>


// ============== toString ============== //
type CanStringified = string | number | bigint | boolean | null | undefined
type StringifyExample<T extends CanStringified> = `${T}`

// ============== 判断数字和0大小关系 ============== //
type NumberLike = number | `${number}`
type IsZeroExample<N extends NumberLike> = N extends (0 | "0") ? true : false
type IsOverZeroExample<N extends NumberLike> = IsZeroExample<N> extends true ? false : StringifyExample<N> extends `${"-"}${infer R}` ? true : false
type IsLowZeroExample<N extends NumberLike> = NotExample<IsOverZeroExample<N>>

// ============== 两数相加 ============== //
type GetTuple<Length extends number = 0> = GetTupleHelper<Length>
type GetTupleHelper<Length extends number = 0, R extends unknown[] = []> = R["length"] extends Length ? R : GetTupleHelper<Length, [...R, unknown]>
type IntAddSingleHelper<n1 extends number, n2 extends number> = [
    ...GetTuple<n1>,
    ...GetTuple<n2>
]['length']
// number
// 正整数（和0）加法，T1，T2最大999
type IntAddSingle<N1 extends number, N2 extends number> = IntAddSingleHelper<N1, N2> extends number ? IntAddSingleHelper<N1, N2> : number

// ============== 比较大小 ============== //
// 通过转换为元组之后进行递归pop比较跟0的大小关系
// T 意为 Tuple 元组
type CompareHelper<
    N1 extends number,
    N2 extends number,
    T1 extends unknown[] = GetTuple<N1>,
    T2 extends unknown[] = GetTuple<N2>
> = IsNotEqual<N1, N2, true> extends true
    ? Or<IsZero<T1["length"]>, IsZero<T2["length"]>> extends true
    ? IsZero<T1["length"]> extends true
    ? false
    : true
    : CompareHelper<array.Pop<T1>["length"], array.Pop<T2>["length"]>
    : false

// number
// 比较两个数字类型大小
type Compare<N1 extends number, N2 extends number> = CompareHelper<N1, N2>

// ============== 两数相减 ============== //
// 通过基于两个数 N1、 N2，创建不同的元组 T1、T2，依次减少两个元组的长度（删除第一位或最后一位），当有一个元组长度为 0 时，
// 就是这个元组对应的数字类型，比另一个数字类型小（或相等，所以也要先判断是否不相等才进行比较）


export type { IsEqual, IntAddSingle }